package Timer;

import java.util.PriorityQueue;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created with IntelliJ IDEA.
 * Description: 重复写一遍计时器
 * User:周次煜
 * Date: 2024-08-08
 * Time：10:53
 */

class MyTimer2 {


    // 用一个优先级队列来存储
    public static PriorityQueue<MyTimerTask2>  queue = new PriorityQueue<>((a,b)->{
//        建立小根堆
        return (int)(a.getDelay()-b.getDelay());
    });


    // 创建个锁对象
    public  static Object locker = new Object();


    // 在构造方法中进行调用
    public MyTimer2() {
        //  开始执行任务
        Thread t = new Thread(()->{
            // 进行死循环不断执行
            while(true) {
                try {
                    synchronized(locker) {
                        // 如果队列为 空就一直进行等待
                        while(queue.isEmpty()) {
                            locker.wait();
                        }

                        MyTimerTask2  current = queue.peek();
                        // 进行判断当前时间是否需要执行
                        if(current.getDelay()<= System.currentTimeMillis()) {
//                            执行任务并且出队列
                            current.run();
                            queue.poll();
                        } else {
                            // 没到时间就进行阻塞等待
                            locker.wait( current.getDelay()- System.currentTimeMillis());
                        }

                    }
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });


        // 开始创建线程
        t.start();
    }



    // 设置时间长度
    public void schedule(Runnable runnable, long delay) {
        synchronized (locker) {
           MyTimerTask2 task2 =  new MyTimerTask2(runnable, delay);

           // 加入队列
           queue.add(task2);

           // 每加入一次就唤醒一次
           locker.notify();
        }

    }



}


/**
 *
 *
 * 这里进行属性的定义
 * 并且初始化并且进行工作
 */

public class MyTimerTask2 {

    // 时间延时大小
    private long delay ;

    public Runnable runnable;

    // 设置延时时间
    public  MyTimerTask2(Runnable runnable,long delay) {
        // 确定一个时间点
        this.delay = delay + System.currentTimeMillis();

        // 任务安排
        this.runnable = runnable;
    }

    // 返回该时间位置
    public long getDelay() {
        return this.delay;
    }



    // 任务执行
    public void run() {
        runnable.run();
    }

    public static void main(String[] args) {
        MyTimer2 t2= new MyTimer2();
        t2.schedule(()->{
            System.out.println("最慢的");
        },  3000);

        t2.schedule(()->{
            System.out.println("较快的");
        },  2000);

        t2.schedule(()->{
            System.out.println("最快的");
        },  1000);

    }


}


